using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

using Dashboard;
using Dashboard.Util;
using Dashboard.Engine;

namespace Dashboard.Engine.Backends
{
	// This is a cluechainer that produces clues
	// by extracting keywords from textblocks.

	public class TextProcessorBackend : Backend, IComponent
	{
		public void Initialize ()
		{
			Engine.MessageBroker.Subscribe ("/event/*", typeof (ClueMessage), OnMessage);
		}

		public void Dispose ()
		{

		}

		private void OnMessage (Message message)
		{
			Engine.Log.Debug ("Processing message");

			ClueMessage clue_message = message as ClueMessage;

			// Extract keywords from the textblocks and
			// construct new clues based on that.

			bool found_keywords = false;

			foreach (Clue clue in clue_message.Clues) {

				// If the clue already contains the
				// dc:keywords property we've probably
				// already processed the clue.
				// FIXME: This is a bit crude.

				if (clue.Properties.Contains ("dc:keywords"))
					continue;

				// We try to extract keywords from all 
				// properties of type dc:text.

				foreach (Property property in clue.Properties.ToArray ()) {
					if (property.Type != "dc:text" || String.IsNullOrEmpty (property.Value))
						continue;
					
					List<string> keywords = ExtractKeywords (property.Value);
					
					if (keywords.Count == 0)
						continue;

					found_keywords = true;
					
					Property keyword_property = new Property("dc:keywords", "dc:collection", String.Join (" ", keywords.ToArray ()));
					
					clue.Properties.Add (keyword_property);
				}
			}
			
			if (found_keywords)
				Engine.MessageBroker.Send (clue_message);
		}
		
		private List<string> ExtractKeywords (string text)
		{
			List<string> keywords = new List<string> ();
			
			try {
				keywords.AddRange (ots_get_keywords (text).Split(','));
				keywords.Reverse ();
			} catch (Exception ex) {
				Engine.Log.Error ("Caught exception while extracting keywords: {0} ({1})", ex.GetType(), ex.Message);
			}
			
			return keywords;
		}
		
		[DllImport("libdashboardglue")]
		static extern string ots_get_keywords (string text);

		public string Name
		{
			get { return "TextProcessor"; }
		}

		public string Description
		{
			get { return ""; }
		}
	}
}
